/**
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

// Example of reading/writing an external serial flash using the PL022 SPI interface

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "hardware/spi.h"

#include "wizchip_conf.h"
#include "w5100s.h"

#define UART_ID uart0
#define BAUD_RATE 115200

#define UART_TX_PIN 0
#define UART_RX_PIN 1

#define SIP_ID spi0



#define SPI_SCK_PIN 18
#define SPI_MOSI_PIN 19
#define SPI_MISO_PIN 16
#define SPI_MISO_CS 17
#define SPI_MISO_RST 20

void wizchip_cs_select_cbfunc(void)
{
    asm volatile("nop \n nop \n nop"); // FIXME
    gpio_put(SPI_MISO_CS, 0);
    asm volatile("nop \n nop \n nop"); // FIXME
}

void wizchip_cs_deselect_cbfunc(void)
{
    asm volatile("nop \n nop \n nop"); // FIXME
    gpio_put(SPI_MISO_CS, 1);
    asm volatile("nop \n nop \n nop"); // FIXME
}

uint8_t wiznet_spi_rb_cbfunc(void)
{
    uint8_t tx_data = 0x00;
    uint8_t rx_data;
    spi_read_blocking(SIP_ID, tx_data, &rx_data, 1);
    return rx_data;
}

void wizchip_spi_wb_cbfunc(uint8_t wb)
{
    spi_write_blocking(SIP_ID, &wb, 1);
}

void gpio_config()
{
    gpio_set_function(SPI_SCK_PIN, GPIO_FUNC_SPI);
    gpio_set_function(SPI_MOSI_PIN, GPIO_FUNC_SPI);
    gpio_set_function(SPI_MISO_PIN, GPIO_FUNC_SPI);
    // Make the SPI pins available to picotool
    bi_decl(bi_3pins_with_func(SPI_MISO_PIN, SPI_MOSI_PIN, SPI_SCK_PIN, GPIO_FUNC_SPI));

    // Chip select is active-low, so we'll initialise it to a driven-high state
    gpio_init(SPI_MISO_CS);
    gpio_put(SPI_MISO_CS, 1);
    gpio_set_dir(SPI_MISO_CS, GPIO_OUT);
}


int main()
{
    uint8_t wizchip_version = 0x00;
    wiz_NetInfo net_info = {
        .mac = {0x00, 0x08, 0xdc, 0x1e, 0xed, 0x2e},
        .ip = {192, 168, 1, 235},
        .sn = {255, 255, 255, 0},
        .gw = {192, 168, 1, 1},
    };

    stdio_init_all();
    
    // Enable SPI 0 at 8 MHz and co,nnect to GPIOs
    spi_init(SIP_ID, 8 * 1000 * 1000);
    gpio_config();
    sleep_ms(2000);
    reg_wizchip_cs_cbfunc(wizchip_cs_select_cbfunc, wizchip_cs_deselect_cbfunc);
    reg_wizchip_spi_cbfunc(wiznet_spi_rb_cbfunc, wizchip_spi_wb_cbfunc);
  
    printf("W5100s network install example.\r\n");

    while (true)
    {
        wizchip_version = getVER();
        printf("wizchip_version = %02X\r\n", wizchip_version);
        sleep_ms(1000);
        if (wizchip_version == 0x51)
        {
            wizchip_setnetinfo(&net_info);
            printf("mac: %02X-%02X-%02X-%02X-%02X-%02X\r\n", net_info.mac[0], net_info.mac[1], net_info.mac[2], net_info.mac[3], net_info.mac[4], net_info.mac[5]);
            printf("ip: %d.%d.%d.%d\r\n", net_info.ip[0], net_info.ip[1], net_info.ip[2], net_info.ip[3]);
            printf("mask: %d.%d.%d.%d\r\n", net_info.sn[0], net_info.sn[1], net_info.sn[2], net_info.sn[3]);
            printf("gw: %d.%d.%d.%d\r\n", net_info.gw[0], net_info.gw[1], net_info.gw[2], net_info.gw[3]);
        }
        break;
    }

    while (true)
    {
        sleep_ms(1000);
    }
}
